/*
 * $Id: $
 */
package org.rcgwt.client.ui.grid.event;

import org.rcgwt.client.ui.grid.internal.model.IViewModel;

import com.google.gwt.event.shared.GwtEvent;

/**
 * 
 * @author Olivier Oeuillot (latest modification by $Author: $)
 * @version $Revision: $ $Date: $
 */
public class FocusElementEvent<I> extends GwtEvent<FocusElementHandler<I>> {

    /**
     * Handler type.
     */
    private static Type<FocusElementHandler< ? >> TYPE;

    /**
     * Fires a Focus event on all registered handlers in the handler manager.If
     * no such handlers exist, this method will do nothing.
     * 
     * @param <I>
     *            the selected item type
     * @param source
     *            the source of the handlers
     * @param oldELement
     *            the selected item
     */
    public static <I> void fire(HasFocusElementHandlers<I> source,
            I oldElementModel, I newElementModel, IViewModel oldViewModel,
            IViewModel newViewModel) {
        if (TYPE != null) {
            FocusElementEvent<I> event = new FocusElementEvent<I>(oldElementModel,
                    newElementModel, oldViewModel, newViewModel);
            source.fireEvent(event);
        }
    }

    /**
     * Gets the type associated with this event.
     * 
     * @return returns the handler type
     */
    public static Type<FocusElementHandler< ? >> getType() {
        if (TYPE == null) {
            TYPE = new Type<FocusElementHandler< ? >>();
        }
        return TYPE;
    }

    private final I oldElementModel;

    private final I newElementModel;

    private final IViewModel oldViewModel;

    private final IViewModel newViewModel;

    /**
     * Creates a new Focus event.
     * 
     * @param oldElement
     *            selected item
     */
    protected FocusElementEvent(I oldElement, I newElement,
            IViewModel oldViewModel, IViewModel newViewModel) {
        this.oldElementModel = oldElement;
        this.newElementModel = newElement;
        this.oldViewModel = oldViewModel;
        this.newViewModel = newViewModel;
    }

    // The instance knows its BeforeFocusHandler is of type I, but the TYPE
    // field itself does not, so we have to do an unsafe cast here.
    @SuppressWarnings("unchecked")
    @Override
    public final Type<FocusElementHandler<I>> getAssociatedType() {
        return (Type) TYPE;
    }

    /**
     * Gets the selected item.
     * 
     * @return the selected item
     */
    public I getOldElementModel() {
        return oldElementModel;
    }

    public I getNewElementModel() {
        return newElementModel;
    }

    public IViewModel getOldViewModel() {
        return oldViewModel;
    }

    public IViewModel getNewViewModel() {
        return newViewModel;
    }

    @Override
    protected void dispatch(FocusElementHandler<I> handler) {
        handler.onFocus(this);
    }
}
